package com.to8to.autotask.server;

import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.leader.LeaderSelector;
import org.apache.curator.framework.recipes.leader.LeaderSelectorListenerAdapter;
import org.apache.curator.utils.EnsurePath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.to8to.autotask.scheduler.AutoTaskScheduler;
import com.to8to.es.util.LogUtil;
import com.to8to.kitt.esb.ZK;
import com.to8to.kitt.zkutils.LeaderElection;
import com.to8to.thrift.crm.autotask.AutoTaskService;

/**
 * AutoTaskSchedulerServer.java
 * 作 者：atom.liu
 * 版 本：v2.0
 * 日 期：2015年1月5日
 * 描 述：自动调度任务启动主函数类。
 */
public class AutoTaskSchedulerServer extends DeamonWithTaskProperty
{
    private static final Logger logger = LoggerFactory.getLogger(AutoTaskSchedulerServer.class);

    private static final String ELEC_PATH = "/elect/" + AutoTaskSchedulerServer.class.getSimpleName();

    public static void main(String[] args)
    {
        String instance = "3";
        if (args.length > 0)
            instance = args[0];

        AutoTaskSchedulerServer server = new AutoTaskSchedulerServer();
        //因为该服务的实例在节点中心是挂在com.to8to.thrift.crm.autotask.AutoTaskService下面，所以这里传入的依然是AutoTaskService
        server.start(AutoTaskService.class.getName(), instance);

        try
        {
            //启动自动调度任务
            EnsurePath ensurePath = new EnsurePath(ELEC_PATH);
            ensurePath.ensure(ZK.ZK_CLIENT.getZookeeperClient());

            //选举leader，获得leader之后，会回调takeLeadership方法
            LeaderSelector selector = LeaderElection.elect(ELEC_PATH, new LeaderSelectorListenerAdapter()
            {
                @Override
                public void takeLeadership(CuratorFramework client) throws Exception
                {
                    logger.info("获得Leader，将启动自动任务！");
                    AutoTaskScheduler.stop();
                    AutoTaskScheduler.start();
                    try
                    {
                        new CountDownLatch(1).await();
                    }
                    catch (Exception e)
                    {
                        logger.error("LeaderLatch await over!{} \n {}", e, LogUtil.logStackTrace(e));
                        AutoTaskScheduler.stop();
                    }
                }
            }, true);

            while (true)
            {
                try
                {
                    //如果当前进程不是leader，则stop掉停止任务，防止多个进程同时再跑自动任务，保证只有获得leader的进程执行自动任务。
                    TimeUnit.MINUTES.sleep(5);
                    List<String> list = ZK.ZK_CLIENT.getChildren().forPath(ELEC_PATH);
                    logger.debug("当前子节点: " + list);
                    boolean flag = selector.hasLeadership();
                    logger.debug(String.format("是否是Leader ： [ %s ]", flag));
                    if (!flag)
                        AutoTaskScheduler.stop();
                }
                catch (InterruptedException e)
                {
                    logger.error("InterruptedException！{} \n {}", e, LogUtil.logStackTrace(e));
                }
            }
        }
        catch (Exception e)
        {
            logger.error("AutoTaskSchedulerServer 启动失败！{} \n {}", e, LogUtil.logStackTrace(e));
        }
    }
}
